﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using XNATweener;
using tactics.Interfaces;

namespace tactics.Commands
{
    public class MoveUnitCommand : BaseCommand
    {
        Unit unit;
        Utility.Pair<int, int> moveTo;
        float moveSpeed = 0.25f;

        Stack<Utility.Pair<int, int>> movePath;

        public MoveUnitCommand(Unit unitIn, Utility.Pair<int, int> coordIn, Dictionary<int, int> moveDict)
        {
            Finished = false;
            unit = unitIn;
            moveTo = coordIn;
            movePath = new Stack<tactics.Utility.Pair<int, int>>();

            foreach (KeyValuePair<int, int> kvp in moveDict)
            {
                Utility.Pair<int, int> coord = TacticsEngine.Instance.Game.TerrainMap.GetCoordFromIndex(kvp.Key);
                movePath.Push(coord);
            }
        }

        public override void Execute()
        {
            var scale = TacticsEngine.Instance.Game.TerrainMap.Scale;
            var scale2 = scale / 2;

            Utility.Pair<int, int> coord = movePath.Pop();

            var tweenX = new Tweener(unit, "WorldX", unit.worldPosition.X, coord.First * scale + scale2, moveSpeed, (TweeningFunction)Delegate.CreateDelegate(typeof(TweeningFunction), typeof(Linear), "EaseIn"));
            var tweenY = new Tweener(unit, "WorldY", unit.worldPosition.Y, TacticsEngine.Instance.Game.TerrainMap.GetAverageHeight(coord.First, coord.Second) * scale, moveSpeed, (TweeningFunction)Delegate.CreateDelegate(typeof(TweeningFunction), typeof(Linear), "EaseIn"));
            var tweenZ = new Tweener(unit, "WorldZ", unit.worldPosition.Z, coord.Second * scale + scale2, moveSpeed, (TweeningFunction)Delegate.CreateDelegate(typeof(TweeningFunction), typeof(Linear), "EaseIn"));
            tweenX.Ended += new Tweener.EndHandler(tweenX_Ended);

            TacticsEngine.Instance.AnimationManager.AddTween(tweenX);
            TacticsEngine.Instance.AnimationManager.AddTween(tweenY);
            TacticsEngine.Instance.AnimationManager.AddTween(tweenZ);

            TacticsEngine.Instance.Game.TurnManager.UnitTurn = unit;
            TacticsEngine.Instance.Game.TurnManager.UnitMoved = true;

            if (TacticsEngine.Instance.Game.TurnManager.AbilityUsed)
                TacticsEngine.Instance.Game.TurnManager.AdvanceTurn();
            else
                TacticsEngine.Instance.Game.TurnManager.UpdatePlayerMap();

            Finished = true;
        }

        void tweenX_Ended(Tweener ended)
        {
            if (movePath.Count <= 0)
            {
                unit.Move(moveTo.First, moveTo.Second, true);
                return;
            }

            var scale = TacticsEngine.Instance.Game.TerrainMap.Scale;
            var scale2 = scale / 2;

            Utility.Pair<int, int> coord = movePath.Pop();

            var tweenX = new Tweener(unit, "WorldX", unit.worldPosition.X, coord.First * scale + scale2, moveSpeed, (TweeningFunction)Delegate.CreateDelegate(typeof(TweeningFunction), typeof(Linear), "EaseIn"));
            var tweenY = new Tweener(unit, "WorldY", unit.worldPosition.Y, TacticsEngine.Instance.Game.TerrainMap.GetAverageHeight(coord.First, coord.Second), moveSpeed, (TweeningFunction)Delegate.CreateDelegate(typeof(TweeningFunction), typeof(Linear), "EaseIn"));
            var tweenZ = new Tweener(unit, "WorldZ", unit.worldPosition.Z, coord.Second * scale + scale2, moveSpeed, (TweeningFunction)Delegate.CreateDelegate(typeof(TweeningFunction), typeof(Linear), "EaseIn"));

            tweenX.Ended += new Tweener.EndHandler(tweenX_Ended);

            TacticsEngine.Instance.AnimationManager.AddTween(tweenX);
            TacticsEngine.Instance.AnimationManager.AddTween(tweenY);
            TacticsEngine.Instance.AnimationManager.AddTween(tweenZ);
        }
    }
}